package com.bs.demo.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.util.JdbcConstants;
import com.bs.demo.annotation.BingShaoLog;
import com.bs.demo.feign.AuthFeign;
import com.bs.demo.service.CasesService;
import com.bs.common.utils.Result;
import com.bs.demo.vo.TestVo;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.bs.demo.interceptor.DemoRestInterceptor.loginUserThreadLocal;

/**
 * @author bingshao
 * @date 2022/9/21
 **/
@RestController
@RequestMapping("/demo")
public class DemoController {

    @Resource
    private AuthFeign authFeign;

    @Resource
    private CasesService casesService;

    @GetMapping("/test")
    public void demo1() {
        String username = loginUserThreadLocal.get().getUsername();
        authFeign.test();
        System.out.println(username);
    }

    @GetMapping("/write")
    public void write() throws InterruptedException {
        casesService.write();
    }

    @BingShaoLog
    @PostMapping("/test2")
    public void test2(@RequestBody TestVo testVo) {
        System.out.println("============test2.testVo.name============" + testVo.getName());
        System.out.println("============test2============");
    }

    @BingShaoLog
    @PostMapping("/test3")
    public Result<String> test3() {
        System.out.println("============test3============");
        return Result.success("ok");
    }

    @BingShaoLog
    @PostMapping("/test4/{id}")
    public Result<Long> test4(@PathVariable("id") Long id) {
        int a = 10 / 0;
        System.out.println("============test4============");
        return Result.success(id);
    }

    @PostMapping("/test5")
    public void test5(TestVo testVo) {
        System.out.println("============test5.testVo.name============" + testVo.getName());
        System.out.println("============test5============");
    }

    @PostMapping("/test6")
    public void test6(@RequestBody TestVo testVo) {
        System.out.println("============test6.testVo.name============" + testVo.getName());
        System.out.println("============test6============");
    }

    @PostMapping("/test7")
    public String test7() {
        return "ok";
    }

    public static void main(String[] args) {
//        String sql = "select a.name,b.name as b_name,a.sex,a.id,b.age from ac as a left join bc as b on a.sex = b.sex";
//        String sql = "select id,name,sex from cases";
        String sql = "select a.id,a.name,b.sex,c.age from cases as a left join cases1 as b on a.id = b.in left join cases2 as c on a.name = c.name";
        String dbType = JdbcConstants.MYSQL;
        SQLStatementParser parser = new MySqlStatementParser(sql);
        SQLStatement sqlStatement = parser.parseStatement();
        MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
        sqlStatement.accept(visitor);

        String tableSql = sql.trim().substring(sql.indexOf("from") + 4).trim();
        List<List<String>> collect = Arrays.stream(tableSql.split("join")).map(String::trim).map(s -> Arrays.stream(s.split("\\s+")
        ).collect(Collectors.toList())).collect(Collectors.toList());


        List<String> tableNameList = visitor.getTables().keySet().stream().map(TableStat.Name::getName).collect(Collectors.toList());
        Map<String, String> map = new HashMap<>(8);
        collect.forEach(stringList -> {
            for (String tableName : tableNameList) {
                int index = stringList.indexOf(tableName);
                if (index < 0) {
                    continue;
                }
                if (stringList.size() > index + 2) {
                    if ("as".equalsIgnoreCase(stringList.get(index + 1))) {
                        map.put(stringList.get(index + 2), tableName);
                    } else {
                        map.put(stringList.get(index + 1), tableName);
                    }
                    break;
                }
            }
        });


        String selectConnect = sql.substring(sql.indexOf("select") + 6, sql.indexOf("from")).trim();
        List<String> selectFieldList = Arrays.stream(selectConnect.split(",")).map(s -> s.split("\\s+")[0]).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(map)) {
            String tableName = sql.substring(sql.indexOf("from") + 4).trim().split("\\s+")[0];
            selectFieldList = selectFieldList.stream().map(selectField -> {
                        if (!selectField.contains("\\.")) {
                            return tableName + "." + selectField;
                        }
                        return selectField;
                    }
            ).map(selectField -> {
                String[] split = selectField.split("\\.");
                return selectField.replaceFirst(split[0], tableName);
            }).collect(Collectors.toList());
        } else {
            selectFieldList = selectFieldList.stream().map(selectField -> {
                String[] split = selectField.split("\\.");
                String tableName = map.get(split[0]);
                return selectField.replaceFirst(split[0], tableName);
            }).collect(Collectors.toList());
        }

        List<Map<String, String>> tableFieldMapList = new LinkedList<>();

        selectFieldList.forEach(selectField -> {
            Map<String, String> tableFieldMap = new HashMap<>(2);
            String[] split = selectField.split("\\.");
            tableFieldMap.put(split[0], split[1]);
            tableFieldMapList.add(tableFieldMap);
        });

        tableFieldMapList.forEach(System.out::println);

        //获取字段名称
//        System.out.println("fields : " + visitor.getColumns());
//        visitor.getColumns().forEach(column -> {
//            System.out.println(column.getName());
//            System.out.println(column.getTable());
//            System.out.println(column.getFullName());
//        });


        //格式化输出
//        String result = SQLUtils.format(sql, dbType);
//        System.out.println(result); // 缺省大写格式
//        List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, dbType);
//        //解析出的独立语句的个数
//        System.out.println("size is:" + stmtList.size());
//        for (int i = 0; i < stmtList.size(); i++) {
//
//            SQLStatement stmt = stmtList.get(i);
//            MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
//            stmt.accept(visitor);
//
//            //获取操作方法名称,依赖于表名称
//            System.out.println("Manipulation : " + visitor.getTables());
//            //获取字段名称
//            System.out.println("fields : " + visitor.getColumns());
//
//
////            //获取排序名称
////            System.out.println("getOrderByColumns : " + visitor.getOrderByColumns());
////            //获取分组
////            System.out.println("getGroupByColumns : " + visitor.getGroupByColumns());
//        }

    }

//    public static void main(String[] args) throws Exception {
////        Object o1 = "冰少";
////        Object o2 = "男";
////        JSONObject jsonObject = new JSONObject();
////        jsonObject.put("name",o1);
////        jsonObject.put("sex",o2);
////        TestVo testVo = JSONObject.parseObject(jsonObject.toJSONString(), TestVo.class);
//        Class<?> aClass = Class.forName("com.bs.demo.vo.TestVo");
//        Object o = aClass.newInstance();
//        Field name = aClass.getDeclaredField("name");
//        name.setAccessible(true);
//        name.set(o, "冰少");
//
//        Class<?> aClass1 = Class.forName("com.bs.demo.vo.User");
//        Object o1 = aClass1.newInstance();
//        Field age = aClass1.getDeclaredField("age");
//        age.setAccessible(true);
//        age.set(o1, 24);
//
//        Method test = aClass.getMethod("test",aClass1);
//        Object invoke = test.invoke(o, o1);
//
//        System.out.println(invoke.toString());
//    }


}


